<template>
  <div class="monitor-box">
    <div class="left-box">
      <div class="control-box">
        <div class="search-box box-shadow">
          <a-form>
            <a-form-item label="标段">
              <a-select
                  v-model:value="cellQueryFormState.sections[0].sectionId">
                <a-select-option
                    v-for="section in sections"
                    :key="section.sectionId" :value="section.sectionId">
                  {{section.sectionName}}
                </a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item label="仅显示当日施工单元">
              <a-switch
                  :defaultChecked="cellQueryFormState.workToday==1"
                  @change="()=>{cellQueryFormState.workToday=cellQueryFormState.workToday==1?undefined:1}"/>
            </a-form-item>
            <a-form-item label="单元状态">
              <a-select
                  v-model:value="cellQueryFormState.status">
                <a-select-option
                    v-for="cellStatus in cellStatusDict.dict2"
                    :key="cellStatus.statusCode" :value="cellStatus.statusCode">
                  {{cellStatus.statusName}}
                </a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item label="单元名称">
              <a-input v-model:value="cellQueryFormState.cellName"></a-input>
            </a-form-item>
            <a-form-item>
              <a-button @click="getCellBaseInfoList" type="primary">查询</a-button>
            </a-form-item>
          </a-form>
        </div>
        <div class="map-control box-shadow">
          <a-checkbox-group
              v-model:value="baseControl"
              @change="clickMapControl">
            <span class="map-control-title">基础数据</span>
            <a-row>
              <a-col :span="12">
                <a-checkbox value="border">单元边界</a-checkbox>
              </a-col>
            </a-row>
            <span class="map-control-title">碾压数据</span>
            <a-row>
              <a-col :span="12">
                <a-checkbox value="fact"  :disabled="disabled">振碾轨迹</a-checkbox>
              </a-col>
              <a-col :span="12">
                <a-checkbox value="real_comp"  :disabled="disabled">实时数据</a-checkbox>
              </a-col>
            </a-row>
            <span class="map-control-title">摊铺数据</span>
            <a-row>
              <a-col :span="12">
                <a-checkbox value="fact" :disabled="disabledTP">摊铺轨迹</a-checkbox>
              </a-col>
              <a-col :span="12">
                <a-checkbox value="real_pav" :disabled="disabledTP">实时数据</a-checkbox>
              </a-col>
            </a-row>
          </a-checkbox-group>
        </div>
      </div>
      <div class="cell-table-box box-shadow">
        <div class="table-box-header">
          单元列表
        </div>
        <div class="table-box-center">
          <a-table
              :scroll="{y:setHeight('.table-box-center', 125) + 'px'}"
              :data-source="cellBaseInfoList.cellInfo"
              :rowKey="(record) => record.cellId"
              @change="getCellBaseInfoList"
              :pagination="{
                'current':cellBaseInfoList.startPage,
                'total':cellBaseInfoList.totalCount,
                'pageSize':cellBaseInfoList.everyPage,
                'showLessItems':true
              }">
            <a-table-column title="归属标段" data-index="sectionName"></a-table-column>
            <a-table-column title="单元名称" data-index="cellName"></a-table-column>
            <a-table-column title="工艺类型" data-index="kind" width="80px">
              <template #default="{text}">
                <div>{{kindDict.getNameByCode(text)}}</div>
              </template>
            </a-table-column>
            <a-table-column title="操作" data-index="cellId" width="50px">
              <template #default="{text,record}">
                <div class="table-icon-box">
                  <div @click="handleCell(record)">
                    <EditOutlined/>
                  </div>
                </div>
              </template>
            </a-table-column>
            <a-table-column title="启停" data-index="cellStatus" width="50px">
              <template #default="{text,record}">
                <a-switch :defaultChecked="text!=0" @change="setCellStatus(record)"/>
              </template>
            </a-table-column>
          </a-table>
        </div>
      </div>
    </div>
    <div class="right-box">
      <div class="base-info-box box-shadow">
        <a-descriptions :column="4">
          <a-descriptions-item label="单元名称" :span="1">
            {{inCellBaseInfo?inCellBaseInfo.cellName:'--'}}
          </a-descriptions-item>
          <a-descriptions-item label="创建时间" :span="1">
            {{inCellBaseInfo?inCellBaseInfo.gtmCreateTime:'--'}}
          </a-descriptions-item>
          <a-descriptions-item label="工艺类型" :span="1">
            {{inCellBaseInfo?kindDict.getNameByCode(inCellBaseInfo.kind):'--'}}
          </a-descriptions-item>
          <a-descriptions-item label="归属标段" :span="1">
            {{inCellBaseInfo?inCellBaseInfo.sectionName:'--'}}
          </a-descriptions-item>
          <a-descriptions-item label="区域面积" :span="1">
            {{inCellBaseInfo?inCellBaseInfo.area:'--'}}
          </a-descriptions-item>
          <a-descriptions-item label="创建账号" :span="1">
            {{inCellBaseInfo?inCellBaseInfo.userName:'--'}}
          </a-descriptions-item>
          <a-descriptions-item label="三检状态" :span="1">
            {{ tpiStatue ? tpiStatue : '--' }}
          </a-descriptions-item>
        </a-descriptions>
      </div>
      <div class="map-box box-shadow">
        <div class="map-event-control">
          <div @click="clickMapEvent(1)" v-if="disabledTP" :class="{'map-control-button':true,'map-control-active':pavLineInfo.type==1}">碾压详情</div>
          <div @click="clickMapEvent(2)" v-if="disabled" :class="{'map-control-button':true,'map-control-active':pavLineInfo.type==2}">摊铺详情</div>
        </div>
        <div
            class="point-info"
            v-show="pavLineInfo.show&&pavLineInfo.type==1"
            v-if="disabledTP">
          <div class="point-header">
            <span>
              碾压
            </span>
            <CloseOutlined @click="pavLineInfo.show = false"/>
          </div>
          <div class="point-content">
            <div class="info">
              <a-row>
                <a-col :span="10">单元名称</a-col>
                <a-col :span="14">{{pavLineInfo.cellName}}</a-col>
              </a-row>
              <a-row>
                <a-col :span="10">P坐标</a-col>
                <a-col :span="14">{{pavLineInfo.a}}</a-col>
              </a-row>
              <a-row>
                <a-col :span="10">H坐标</a-col>
                <a-col :span="14">{{pavLineInfo.b}}</a-col>
              </a-row>
              <a-row>
                <a-col :span="10">遍数</a-col>
                <a-col :span="14">{{pavLineInfo.workTimes}}</a-col>
              </a-row>
            </div>
          </div>
        </div>
        <div
            class="point-info"
            v-show="pavLineInfo.show&&pavLineInfo.type==2"
            v-if="disabled">
          <div class="point-header">
            <span>
              摊铺
            </span>
            <CloseOutlined @click="pavLineInfo.show = false"/>
          </div>
          <div class="point-content">
            <div class="info">
              <a-row>
                <a-col :span="10">单元名称</a-col>
                <a-col :span="14">{{pavLineInfo.cellName}}</a-col>
              </a-row>
              <a-row>
                <a-col :span="10">P坐标</a-col>
                <a-col :span="14">{{pavLineInfo.a}}</a-col>
              </a-row>
              <a-row>
                <a-col :span="10">H坐标</a-col>
                <a-col :span="14">{{pavLineInfo.b}}</a-col>
              </a-row>
              <a-row>
                <a-col :span="10">高程</a-col>
                <a-col :span="14">{{pavLineInfo.workHeight}}</a-col>
              </a-row>
            </div>
          </div>
        </div>
        <div @click="openExAreaModal(inCellBaseInfo?inCellBaseInfo.cellId:0)" class="ex-area-btn"/>
        <div @click="workListInfo.showModal = true" class="work-list-btn"/>
        <!-- 三检按钮 -->
<!--        <a-popover>-->
<!--          <template #content>-->
<!--            <span>三检</span>-->
<!--          </template>-->
<!--          <div-->
<!--              class="tpi-list-btn"-->
<!--              @click="openTpiModal(inCellBaseInfo ? inCellBaseInfo.cellId : 0)"/>-->
<!--        </a-popover>-->
        <div id="mapboxgl-box"></div>
        <div class="draw-save" v-if=isDrawSave>
          <a-button type="default" shape="square" @click="saveDrawArea" size="middle">
            <template #icon>
              <CheckOutlined/>
            </template>
          </a-button>
        </div>
      </div>
    </div>
  </div>
  <SModal
      title="工作设备列表"
      width="480"
      :is-show="workListInfo.showModal"
      @closed="()=>workListInfo.showModal=false">
    <div class="smodal-box smodal-to-cell">
      <a-table
          :scroll="{y:`205px`}"
          :data-source="workListInfo.workList"
          :rowKey="(record) => record.deviceId"
          @change="getToNextCellDevice"
          :pagination="false">
        <a-table-column title="机械编号" data-index="deviceSn"></a-table-column>
        <a-table-column title="机械名称" data-index="deviceName"></a-table-column>
        <a-table-column title="机械类型" data-index="deviceKind">
          <template #default="{text}">
            <div>{{deviceTypeDict.getNameByCode(text)}}</div>
          </template>
        </a-table-column>
      </a-table>
    </div>
  </SModal>
  <SModal
      title="排除区域"
      width="1000"
      height="362"
      :is-show="showExModal"
      @closed="()=>{showExModal = false}">
    <div class="ex-area-modal">
      <div class="ex-table-box">
        <a-table
            :scroll="{y:'180px'}"
            :data-source="exAreaList"
            :rowKey="record => record.serial"
            :pagination="false">
          <a-table-column title="序号" data-index="serial" width="60px"/>
          <a-table-column title="排除时间" data-index="gtmCreateTime"/>
          <a-table-column title="操作人员" data-index="userName" width="100px"/>
          <a-table-column title="排除区域名称" data-index="excludedName" width="160px">
            <template #default="{text,record}">
              <div style="padding: 0 8px">
                <a-input
                    v-model:value="record.excludedName"
                    v-if="record.excludedId < 0"/>
                <span v-else>{{ text }}</span>
              </div>
            </template>
          </a-table-column>
          <a-table-column title="排除原因" data-index="reason">
            <template #default="{text,record}">
              <div style="padding: 0 8px">
                <a-input
                    v-model:value="record.reason"
                    v-if="record.excludedId < 0"/>
                <span v-else>{{ text }}</span>
              </div>
            </template>
          </a-table-column>
          <a-table-column title="面积" data-index="area"/>
          <a-table-column title="排除区域范围" data-index="excludedId" width="140px">
            <template #default="{text,record}">
              <a-button @click="openFileModal(record)" :disabled="record.excludedId > 0"
                        type="primary" ghost
                        style="margin-right: 10px">导入</a-button>
              <a-button @click="drawTheBorder(record)" :disabled="record.excludedId > 0"
                        type="primary" ghost>绘制</a-button>
            </template>
          </a-table-column>
          <a-table-column title="坐标" width="60px">
            <template #default="{text,record, index}">
              <!--              {{ text }}-->
              <div class="icon-box" @click="openCoordinateModel(record)">
                <BorderOuterOutlined />
              </div>
            </template>
          </a-table-column>
          <a-table-column title="操作" data-index="excludedId" width="60px">
            <template #default="{text,record,index}">
              <div
                  class="table-icon-box"
                  style="padding: 0 5px; font-size: 16px">
                <div v-if="text <= 0" @click="saveExArea(record)">
                  <SaveOutlined />
                </div>
                <div v-if="text <= 0" @click="delExArea(record, index)">
                  <DeleteOutlined />
                </div>
                <div v-if="text > 0" @click="delExArea(record, index)">
                  <DeleteOutlined />
                </div>
              </div>
            </template>
          </a-table-column>
        </a-table>
      </div>
      <div class="ex-area-btn-box"><a-button @click="addExArea" type="primary">新增</a-button></div>
    </div>
    <input
        id="read-ex-area-input"
        @change="readBorderFile"
        accept=".txt"
        type="file"
        style="position:absolute;width:0;height:0;opacity:0"/>
  </SModal>
  <SModal
      title="排除区域坐标"
      :width="372"
      :height="350"
      :isShow="showCoordinateModal"
      @closed="() => {showCoordinateModal = false}">
    <div class="coor-table-box">
      <!--      <span>{{ borderList }}</span>-->
      <a-table
          :data-source="borderList"
          :scroll="{y: '180px' }"
          :pagination="false">
        <a-table-column title="P坐标" data-index="first">
          <template #default="{text}">
            {{ text.toFixed(6) }}
          </template>
        </a-table-column>
        <a-table-column title="H坐标" data-index="second">
          <template #default="{text}">
            {{ text.toFixed(6) }}
          </template>
        </a-table-column>
      </a-table>
      <div class="down-btn-box">
        <a-button @click="downloadBorderFile()" type="primary">下载</a-button>
      </div>
    </div>
  </SModal>
  <!-- 三检 -->
  <tpiModal
      :is-show="tpiListInfo.showModal"
      ref="TpiModalInit"
      @closed="() => (tpiListInfo.showModal = false)"
  ></tpiModal>
</template>

<script lang="ts">
import {useStore} from "vuex"
import {defineComponent,reactive,ref,toRefs,onMounted,onBeforeUnmount} from "vue"
import {setHeight} from "@/utils/tableUtils"
import {cellBaseInfo} from "@/hooks/cell/index"
import kindDict from "@/dicts/kindDict"
import cellStatusDict from "@/dicts/cellStatusDict"
import mapboxgl, {AnyLayer, LngLat, Marker, Sources} from "mapbox-gl"
import MapboxDraw from "@mapbox/mapbox-gl-draw";
import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css'
import { TableToExcel } from "@/utils/tyutils/index"
import {EditOutlined,SaveOutlined,DeleteOutlined,CloseOutlined,CheckOutlined,BorderOuterOutlined} from '@ant-design/icons-vue'
import {message} from "ant-design-vue"
import axios from "axios"
import qs from "qs"
import redLine from "@/assets/data/redLine.ts"
import "mapbox-gl/dist/mapbox-gl.css"
import {MqttOptions,MqttService} from "@/utils/mqttService"
import config from "@/config/index"
import SModal from "@/components/SModal/index.vue"
import deviceTypeDict from "@/dicts/deviceTypeDict"
import moment from 'moment'
import lodash from "lodash"
// 三检
import tpiModal from "@/components/SModal/TpiModal.vue";

interface MapLayerRequestInfo{
  craft:string|null
  cellId:number|null
  type:string|null
}
class PavLineInfo {
  cellId=-1
  cellName=""
  lat=<any>null
  lng=<any>null
  x=<number|null>null
  y=<number|null>null
  a=<any>null
  b=<any>null
  workTimes=<number|null>null
  workHeight=<number|null>null
  type=<any>undefined
  show=false
}
interface MapDeviceInfo{
  deviceId:number
  deviceInfo:any
  deviceMarker:Marker
}

export default defineComponent({
  setup(){
    const store = useStore()
    const userName = ref(JSON.parse(JSON.stringify(store.getters["userinfo/getUserInfo"])).username)
    const sections = ref(JSON.parse(JSON.stringify(store.getters["userinfo/getUserSection"])))
    const {
      cellQueryFormRef,cellQueryFormState,cellBaseInfoList,inCellBaseInfo,
      getCellBaseInfoList,setCellStatus,getCellBaseInfo
    } = cellBaseInfo()
    cellQueryFormState.value.sections[0].kind = [8,9]
    const workListInfo = ref({
      showModal: false,
      workList: new Array<any>()
    })
    const exAreaInfo = reactive({
      uploadFileRecord: <any>null,
      showExModal: false,
      exAreaList: new Array<any>()
    })
    let isDrawSave = ref(false)
    // 排除区域坐标点
    const coordinateList = reactive({
      borderList: new Array<any>()
    })
    const showCoordinateModal = ref(false)
    // 排除区域显示序号
    const exAreaSerial = reactive({
      data: {
        type: 'FeatureCollection',
        features: new Array<any>()
      }
    })
    const mapControl = reactive({
      baseControl: new Array<string>(),
      pavLineInfo: new PavLineInfo()
    })
    // 三检
    const TpiModalInit = ref()
    const tpiListInfo = ref({
      showModal: false,
      tpiList: new Array<any>()
    })
    const tpiStatue = ref()

    const realMapInfo = reactive({
      deviceList: new Array<MapDeviceInfo>(),  // 设备信息列表(主要用于marker)
      realSourceName: 'real_pav',
      realSource: { // 实时施工数据源列表
        type: "FeatureCollection",
        features: new Array<any>()
      },
      realLayerName: 'real_pav', // 实时施工图层列表
      subscribeList: new Array<string>() // 订阅设备列表
    })

    let maps:any
    let draw: any
    let drawData: any

    const getCellTpiStatue = (cellId: number) => {
      const userinfo = store.getters['userinfo/getUserInfo']
      if (userinfo) {
        // 修-改
        const url =
            config.cityUrlPath + '/detection/work-unit/' + cellId + '/status'
        axios.get(url).then((res: any) => {
          if (res.success) {
            if (res.data.length > 0) {
              tpiStatue.value = res.data[0].status
            }
          }
        })
      }
    }
    // 三检状态
    const getAreaStatus = (cellId: number) => {
      const userinfo = store.getters['userinfo/getUserInfo']
      if (userinfo) {
        const url = config.cityUrlPath + '/detectionTest/detection/getAreaStatusbySysID?id=' + cellId
        axios.get(url).then((res: any) => {
          if (res.code == 0) {
            if (res.data == -1) {
              tpiStatue.value = '待检测'
            } else if (res.data == 0) {
              tpiStatue.value = '不合格'
            } else if (res.data == 1) {
              tpiStatue.value = '合格'
            }
          }
        })
      }
    }
    // 初始化地图
    const initMap = ()=>{
      mapboxgl.accessToken = config.map.accessToken
      let mapSource:Sources = {
        google: {
          type: "raster",
          tiles: [
            config.map.baseLayer1URL,
          ],
          tileSize: 256,
        },
      }
      let layers:AnyLayer[] = [
        {
          id: "google-tiles1",
          type: "raster",
          source: "google",
        },
      ]
      maps = {
        map:new mapboxgl.Map({
          container: "mapboxgl-box",
          style: {
            version: 8,
            sources: mapSource,
            layers: layers,
            glyphs: "mapbox://fonts/mapbox/{fontstack}/{range}.pbf"
          },
          minZoom: 5,
          maxZoom:20,
          center: config.map.center,
          zoom: config.map.zoom,
          attributionControl: false
        }),
        sourceList: new Set<string>(),
        LayerList: new Set<string>()
      }

      maps.map.on("load",()=>{
        maps.map.addLayer({
          id: "satellite1",
          type: "raster",
          source: {
            type: "raster",
            tiles: [config.map.baseLayer2URL],
          },
        })
        maps.map.addLayer({
          id: "air",
          type: "raster",
          source: {
            type: "raster",
            tiles: [config.map.airUrl],
          },
        })
        maps.map.addSource("redLineSource",{type:"geojson",data:redLine})
        maps.map.addLayer({
          id: "redLineLayer",
          type: "line",
          source: "redLineSource",
          layout: {},
          paint: {
            "line-color":"#ff0000",
            "line-width":2,
            "line-opacity":1
          },
        })
      })

      maps.map.on("click", (e:any)=> {
        //三检
        if (tpiListInfo.value.showModal) {
          //等于true获得坐标显示在弹窗
          var lat = e.lngLat.lat
          var lng = e.lngLat.lng
          transWGS84ToLocal(lat, lng).then((res2: any) => {
            if (res2.data) {
              TpiModalInit.value.setSelAB(
                  res2.data.x.toFixed(2),
                  res2.data.y.toFixed(2)
              )
            } else {
              TpiModalInit.value.setSelAB('', '')
            }
          })
        }
        //end
        let type = mapControl.pavLineInfo.type
        if(type==1){
          getPavLineInfo(e.lngLat.lat,e.lngLat.lng).then((res:any)=>{
            mapControl.pavLineInfo = new PavLineInfo()
            mapControl.pavLineInfo.type = type
            mapControl.pavLineInfo.cellName = inCellBaseInfo.value.cellName
            if(res.data!=null){
              Object.assign(mapControl.pavLineInfo,res.data)
              mapControl.pavLineInfo.lat = parseFloat(res.data.lat).toFixed(6)
              mapControl.pavLineInfo.lng = parseFloat(res.data.lng).toFixed(6)
              transWGS84ToLocal(mapControl.pavLineInfo.lat, mapControl.pavLineInfo.lng).then((res2:any)=>{
                if(res2.data){
                  mapControl.pavLineInfo.a = res2.data.x.toFixed(2)
                  mapControl.pavLineInfo.b = res2.data.y.toFixed(2)
                  mapControl.pavLineInfo.show = true
                }else{
                  mapControl.pavLineInfo.show = false
                }
              })
            }else{
              mapControl.pavLineInfo.show = false
            }
          })
        }else if(type==2){
          getPavInfo(e.lngLat.lat,e.lngLat.lng).then((res:any)=>{
            mapControl.pavLineInfo = new PavLineInfo()
            mapControl.pavLineInfo.type = type
            mapControl.pavLineInfo.cellName = inCellBaseInfo.value.cellName
            if(JSON.stringify(res.data) !== '{}' ){
              Object.assign(mapControl.pavLineInfo,res.data)
              mapControl.pavLineInfo.lat = parseFloat(e.lngLat.lat).toFixed(6)
              mapControl.pavLineInfo.lng = parseFloat(e.lngLat.lng).toFixed(6)
              mapControl.pavLineInfo.workHeight =res.data.localH
              transWGS84ToLocal(mapControl.pavLineInfo.lat, mapControl.pavLineInfo.lng).then((res2:any)=>{
                if(res2.data){
                  mapControl.pavLineInfo.a = res2.data.x.toFixed(2)
                  mapControl.pavLineInfo.b = res2.data.y.toFixed(2)
                  mapControl.pavLineInfo.show = true
                }else{
                  mapControl.pavLineInfo.show = false
                }
              })
              mapControl.pavLineInfo.show = true
            }else {
              mapControl.pavLineInfo.show = false
            }
          })
        }
      })
    }
    //自定义绘图工具
    const initDraw = () => {
      draw = new MapboxDraw({
        displayControlsDefault: false,
        controls: {
          polygon: true,
          trash: true
        },
        defaultMode: 'draw_polygon'
      })
      maps.map.addControl(draw, "top-left")
      maps.map.on('draw.create', () => {
        drawData = draw.getAll();
      })
      maps.map.on('draw.delete', () => {
        drawData = draw.getAll();
      })
      maps.map.on('draw.update', () => {
        drawData = draw.getAll();
      })
      //添加
      maps.map.on('draw.modechange', () => {
        drawData = draw.getAll();
        if (draw.getMode() == 'draw_polygon') {
          let pids: any[] = []
          // ID of the added template empty feature
          const lid = drawData.features[drawData.features.length - 1].id
          drawData.features.forEach((f: any) => {
            if (f.geometry.type === 'Polygon' && f.id !== lid) {
              pids.push(f.id)
            }
          })
          draw.delete(pids)
        }
      })
    }
    // 添加图层
    const addLayer = (layerInfo:MapLayerRequestInfo,callback:Function|null = null)=>{

      if(!maps.map) return
      maps.map.addLayer({
        id: `${layerInfo.type}`,
        type: "raster",
        source: `${layerInfo.type}`,
        paint: {
          "raster-opacity": 1,
        },
      })
      maps.LayerList.add(`${layerInfo.type}`)
    }
    // 添加数据源
    const addSource = (layerInfo:MapLayerRequestInfo,callback:Function|null = null)=>{
      if(!maps.map) return
      maps.map.addSource(`${layerInfo.type}`,{
        type: "raster",
        scheme:"tms",
        tiles: [
          `${config.map.geoServer}${layerInfo.craft}%3A${layerInfo.cellId}_${layerInfo.type}@EPSG%3A900913@png/{z}/{x}/{y}.png`
        ],
        tileSize: 256,
      })
      maps.sourceList.add(`${layerInfo.type}`)
    }

    // 移动地图视角
    const mapToCell = (cellCenter:LngLat)=>{
      if(!maps.map) return
      maps.map.jumpTo({center: cellCenter})
    }
 // 获取施工单元中正在工作设备列表
    const getCellWorkMachineryByCellId = (cell:any)=>{
      return new Promise((resolve, reject)=>{
        let data = {
          cellId: cell.cellId,
          kind: cell.kind
        }
        cell.kind==8 ? data.kind = 8 : data.kind = 3
        axios.post("common/findCellWorkMachineryByCellId",data).then((res:any)=>{
          resolve(res)
        }).catch((err:any)=>{
          reject(err)
        })
      })
    }

    const disabled = ref(false);
    const disabledTP = ref(false);
    // 列表中选择仓面
    const handleCell = (cell:any)=>{
      removeDraw()
      clearSerial()
      let f1 = getCellBaseInfo(cell)
      let f2 = getCellWorkMachineryByCellId(cell)

      Promise.all([f1,f2]).then((res:any)=>{
        // 1.持久化数据
        // 清除旧图层&数据源
        maps.LayerList.forEach((item:any)=>{
          if(maps.map.getLayer(item)){
            maps.map.removeLayer(item)
            maps.LayerList.delete(item)
          }
        })
        maps.sourceList.forEach((item:any)=>{
          if(maps.map.getSource(item)) maps.map.removeSource(item)
        })
        //选择类型可见性
        if(inCellBaseInfo.value.kind=="8"){
          disabled.value=true
          disabledTP.value=false
        }else{
          disabled.value=false
          disabledTP.value=true
        }
        // 添加默认图层(获取边界图形报告，默认摊铺）
        let layerInfo:MapLayerRequestInfo = {
          cellId:inCellBaseInfo.value.cellId,
          craft:"HaErBin-TP",
          type:"border"
        }
        cell.kind == 8 ? layerInfo.craft="HaErBin-TP":layerInfo.craft="HaErBin-NY"

        addSource(layerInfo)
        addLayer(layerInfo)

        // 2.实时数据
        // 先清除旧的实时显示相关的数据,图层,marker
        realMapInfo.deviceList.forEach((item:any)=>{
          item.deviceMarker.remove()
        })
        realMapInfo.deviceList = new Array<MapDeviceInfo>()
        MqttService.unsubscribe(realMapInfo.subscribeList)
        realMapInfo.subscribeList = new Array<string>()
        realMapInfo.realSource.features = new Array<any>()
        if(maps.map.getLayer(realMapInfo.realLayerName)) maps.map.removeLayer(realMapInfo.realLayerName)
        if(maps.map.getSource(realMapInfo.realSourceName)) maps.map.removeSource(realMapInfo.realSourceName)

        // 订阅新选定仓面的设备数据
        workListInfo.value.workList = res[1].data
        res[1].data.forEach((item:any)=>{
          let el = document.createElement("div")
          el.className = "device-paver"
          el.innerText = `${item.deviceName}`
          realMapInfo.deviceList.push({
            deviceId:item.deviceId,
            deviceInfo:item,
            deviceMarker:new mapboxgl.Marker(el).setLngLat([0,0]).setOffset(new mapboxgl.Point(86,-16)).addTo(maps.map)
          })
          //前端接口，实时数据--web订阅
          if(inCellBaseInfo.value.kind == 8){
            MqttService.init(
                `${config.craft.paver.paver_mqtt.ip}`,
                new MqttOptions(`${config.craft.paver.paver_mqtt.userName}`,`${config.craft.paver.paver_mqtt.password}`),
                (topic:any, msg:any)=>{
                  msg = JSON.parse(msg.toString())
                  let deviceListIndex = realMapInfo.deviceList.findIndex((item:any)=>{
                    return item.deviceInfo.deviceSn == msg.sn
                  })

                  if(deviceListIndex<0) return

                  realMapInfo.deviceList[deviceListIndex].deviceMarker.getElement().innerText = `${realMapInfo.deviceList[deviceListIndex].deviceInfo.deviceName},${msg.speed}km/h`
                  realMapInfo.deviceList[deviceListIndex].deviceMarker.setLngLat([msg.longitude,msg.latitude])

                  realMapInfo.realSource.features.push({
                    "type": "Feature",
                    "geometry": {
                      "type": "Polygon",
                      "coordinates": [[
                        [msg.longitude,msg.latitude],
                        [msg.longitudeRight,msg.latitudeRight],
                        [msg.longitudePreRight,msg.latitudePreRight],
                        [msg.longitudePre,msg.latitudePre]
                      ]]
                    }
                  })
                  if(maps.map.getLayer(realMapInfo.realLayerName)) maps.map.removeLayer(realMapInfo.realLayerName)
                  if(maps.map.getSource(realMapInfo.realSourceName)) maps.map.removeSource(realMapInfo.realSourceName)
                  maps.map.addSource(realMapInfo.realSourceName,{type:'geojson',data:realMapInfo.realSource})
                  maps.map.addLayer({
                    id: realMapInfo.realLayerName,
                    type: "fill",
                    source: realMapInfo.realSourceName,
                    paint: {
                      "fill-color": "#0A0A0A",
                      "fill-opacity": 0.3
                    }
                  })
                  maps.LayerList.add(realMapInfo.realLayerName)
                }
            )
            MqttService.subscribe(`${config.craft.paver.paver_mqtt.topic}${item.deviceSn}`)
          }else{
            MqttService.init(
                `${config.craft.paver.comp_mqtt.ip}`,
                new MqttOptions(`${config.craft.paver.comp_mqtt.userName}`,`${config.craft.paver.comp_mqtt.password}`),
                (topic:any, msg:any)=>{
                  msg = JSON.parse(msg.toString())

                  let deviceListIndex = realMapInfo.deviceList.findIndex((item:any)=>{
                    return item.deviceInfo.deviceSn == msg.sn
                  })
                  if(deviceListIndex<0) return

                  realMapInfo.deviceList[deviceListIndex].deviceMarker.getElement().innerText = `${realMapInfo.deviceList[deviceListIndex].deviceInfo.deviceName},${msg.speed}km/h`
                  realMapInfo.deviceList[deviceListIndex].deviceMarker.setLngLat([msg.longitude,msg.latitude])

                  // let degree = (1/(2*Math.PI*Math.cos(2*Math.PI/360*msg.latitude)*6378140/360))*msg.wheelWidth
                  let earthRad = 6378137.0
                  let x1 = msg.longitude * Math.PI / 180 * earthRad
                  let y1 = earthRad / 2 * Math.log((1.0 + Math.sin(msg.latitude * Math.PI / 180)) / (1.0 - Math.sin(msg.latitude * Math.PI / 180)))
                  let xright1 = (x1 + msg.wheelWidth * Math.cos(Math.PI/180*msg.head))
                  let yright1 = (y1 - msg.wheelWidth * Math.sin(Math.PI/180*msg.head))

                  let x2 = msg.longitudePre * Math.PI / 180 * earthRad
                  let y2 = earthRad / 2 * Math.log((1.0 + Math.sin(msg.latitudePre * Math.PI / 180)) / (1.0 - Math.sin(msg.latitudePre * Math.PI / 180)))
                  let xright2 = (x2 + msg.wheelWidth * Math.cos(Math.PI/180*msg.head))
                  let yright2 = (y2 - msg.wheelWidth * Math.sin(Math.PI/180*msg.head))


                  let lng1 = xright1 / 20037508.34 * 180
                  let lat1 = 180 / Math.PI * (2 * Math.atan(Math.exp((yright1 / 20037508.34 * 180) * Math.PI / 180)) - Math.PI / 2)

                  let lng2 = xright2 / 20037508.34 * 180
                  let lat2 = 180 / Math.PI * (2 * Math.atan(Math.exp((yright2 / 20037508.34 * 180) * Math.PI / 180)) - Math.PI / 2)

                  realMapInfo.realSource.features.push({
                    "type": "Feature",
                    "geometry": {
                      "type": "Polygon",
                      "coordinates": [[
                        [msg.longitude,msg.latitude],
                        [lng1,lat1],
                        [lng2,lat2],
                        [msg.longitudePre,msg.latitudePre]
                      ]]
                    }
                  })
                  realMapInfo.realLayerName="real_comp"
                  realMapInfo.realSourceName="real_comp"

                  if(maps.map.getLayer(realMapInfo.realLayerName)) maps.map.removeLayer(realMapInfo.realLayerName)
                  if(maps.map.getSource(realMapInfo.realSourceName)) maps.map.removeSource(realMapInfo.realSourceName)
                  maps.map.addSource(realMapInfo.realSourceName,{type:'geojson',data:realMapInfo.realSource})
                  maps.map.addLayer({
                    id: realMapInfo.realLayerName,
                    type: "fill",
                    source: realMapInfo.realSourceName,
                    paint: {
                      "fill-color": "#0A0A0A",
                      "fill-opacity": 0.3
                    }
                  })
                  maps.LayerList.add(realMapInfo.realLayerName)
                  console.log(realMapInfo.realLayerName,realMapInfo.realSourceName )
                }
            )

            MqttService.subscribe(`${config.craft.paver.comp_mqtt.topic}${item.deviceSn}`)
          }

        })

        // 3.操作界面
        cell.kind==8? mapControl.baseControl = ["border","real_pav"] : mapControl.baseControl = ["border","real_comp"]

        // 跳转位置
        if (res[0].data.centLat && res[0].data.centLon){
          maps.map.setZoom(17)
          let cellCenter = new mapboxgl.LngLat(res[0].data.centLon, res[0].data.centLat);
          mapToCell(cellCenter)
        }
      })
      // 三检
      // getCellTpiStatue(cell.cellId)
      // 新三检
      getAreaStatus(cell.cellId)
      getAllPoint(cell.cellId)
    }

    // 点击图层控制按钮
    const clickMapControl = (res:any)=>{
      if(!inCellBaseInfo.value){
        message.info("请先选择单元后再进行操作")
        return
      }

      let diffList = res.concat(Array.from(maps.LayerList)).filter((cur:any, i:any, arr:any) => {
        return arr.indexOf(cur) === arr.lastIndexOf(cur);
      })

      diffList.forEach((item:any)=>{
        let layerInfo:MapLayerRequestInfo = {
          cellId:inCellBaseInfo.value.cellId,
          craft:"HaErBin-TP",
          type:item
        }
          if (inCellBaseInfo.value.kind == 8 ) {
            layerInfo.craft = "HaErBin-TP"
            if(layerInfo.type!='real_pav'){
              let layer = maps.map.getLayer(`${layerInfo.type}`)
              let source = maps.map.getSource(`${layerInfo.type}`)
              if(!layer && !source){
                // 增加图层及数据源
           console.log(layerInfo )
                addSource(layerInfo)
                addLayer(layerInfo)
              }else if(layer && source){
                // 移除图层
                maps.map.removeLayer(`${layerInfo.type}`)
                maps.LayerList.delete(`${layerInfo.type}`)
              }else if(!layer && source){
                // 增加图层
                addLayer(layerInfo)
              }
            }

          } else {
            layerInfo.craft = "HaErBin-NY"
            if(layerInfo.type!='real_comp'){
              let layer = maps.map.getLayer(`${layerInfo.type}`)
              let source = maps.map.getSource(`${layerInfo.type}`)
              if(!layer && !source){
                // 增加图层及数据源
            console.log(layerInfo )
                addSource(layerInfo)
                addLayer(layerInfo)
              }else if(layer && source){
                // 移除图层
                maps.map.removeLayer(`${layerInfo.type}`)
                maps.LayerList.delete(`${layerInfo.type}`)
              }else if(!layer && source){
                // 增加图层
                addLayer(layerInfo)
              }
            }
          }
      })

    if(inCellBaseInfo.value.kind==8){
      let realTampIndex = diffList.indexOf("real_pav")
//getLayer 获取指定 ID 的图层
      let realLayer = maps.map.getLayer("real_pav")
      console.log(diffList)

      if(!maps.map.getSource(realMapInfo.realSourceName)) maps.map.addSource(realMapInfo.realSourceName,{type:'geojson',data:realMapInfo.realSource})
      if(realTampIndex>=0 && realLayer){ // 若存在,删除
        maps.map.removeLayer("real_pav")
        maps.LayerList.delete(realMapInfo.realLayerName)
      }else if((realTampIndex>=0 && !realLayer) || realLayer){ // 若不存在,增加
        if(realLayer) maps.map.removeLayer("real_pav")
        maps.map.addLayer({
          id: realMapInfo.realLayerName,
          type: "fill",
          source: realMapInfo.realSourceName,
          paint: {
            "fill-color": "#0A0A0A",
            "fill-opacity": 0.3
          }
        })
        maps.LayerList.add(realMapInfo.realLayerName)
      }
  }else{
      let reaCoIndex = diffList.indexOf("real_comp")
//getLayer 获取指定 ID 的图层
      let realLayer2 = maps.map.getLayer("real_comp")
      console.log(diffList)
      realMapInfo.realSourceName="real_comp"
      realMapInfo.realLayerName="real_comp"
      if(!maps.map.getSource(realMapInfo.realSourceName)) maps.map.addSource(realMapInfo.realSourceName,{type:'geojson',data:realMapInfo.realSource})
      if(reaCoIndex>=0 && realLayer2){ // 若存在,删除
        maps.map.removeLayer("real_comp")
        maps.LayerList.delete(realMapInfo.realLayerName)
      }else if((reaCoIndex>=0 && !realLayer2) || realLayer2){ // 若不存在,增加
        if(realLayer2) maps.map.removeLayer("real_comp")
        maps.map.addLayer({
          id: realMapInfo.realLayerName,
          type: "fill",
          source: realMapInfo.realSourceName,
          paint: {
            "fill-color": "#0A0A0A",
            "fill-opacity": 0.3
          }
        })
        maps.LayerList.add(realMapInfo.realLayerName)
      }
      }
    }
    // 点击地图
    const clickMapEvent = (type:number)=>{
      tpiListInfo.value.showModal = false
      mapControl.pavLineInfo.show = false
      mapControl.pavLineInfo.type = mapControl.pavLineInfo.type==type?-1:type
    }
    function transWGS84ToLocal1(latitude: number, longitude: number){
      return new Promise((resolve, reject) => {
        axios
            .post('/common/transWGS84ToLocal', { lat: latitude, lng: longitude })
            .then((res: any) => {
              resolve(res)
            })
            .catch((err: any) => {
              reject(err)
            })
      })
    }
//84转AB
    const transWGS84ToLocal = (latitude:number,longitude:number)=>{
      return new Promise((resolve,reject)=>{
        axios.post("/common/transWGS84ToLocal",{lat:latitude,lng:longitude}).then((res:any)=>{
          resolve(res)
        }).catch((err:any)=>{
          reject(err)
        })
      })
    }
    // 获取摊铺压实信息
    const getPavLineInfo = (latitude:number,longitude:number)=>{
      return new Promise((resolve,reject)=>{
        if(!inCellBaseInfo.value){
          message.info("请先选择单元后再进行操作")
          return
        }
//碾压详情部分  根据经纬度获取碾压遍数
        let cellId = inCellBaseInfo.value.cellId
        axios.post("nyMap/getWorkTimesbyCoord",
            qs.stringify({cellID:cellId,lat:latitude,lng:longitude}),{
              headers: {'Content-Type': 'application/x-www-form-urlencoded'}
            }).then((res:any)=>{
          resolve(res)
        }).catch((err:any)=>{
          reject(err)
        })
      })
    }
  //获取摊铺数据
    const getPavInfo = (latitude:number,longitude:number)=>{
      return new Promise((resolve,reject)=>{
        if(!inCellBaseInfo.value){
          message.info("请先选择单元后再进行操作")
          return
        }
//摊铺详情部分  根据经纬度获取摊铺高程
        let cellId = inCellBaseInfo.value.cellId
        axios.post("pave/findPaveHeight",
           {cellId:cellId,latitude:latitude,longitude:longitude}
            ).then((res:any)=>{
          resolve(res)
        }).catch((err:any)=>{
          reject(err)
        })
      })
    }
    async function requestSomething(borderAry:any) {
      for (let i = 0; i < borderAry.length - 1; i++) {
        let pointAry = borderAry[i]
        await transWGS84ToLocal1(pointAry[1], pointAry[0]).then((res: any) => {
          if (res.data) {
            exAreaInfo.uploadFileRecord.border.first.push(res.data.x)
            exAreaInfo.uploadFileRecord.border.second.push(res.data.y)
            console.log("---------")
            console.log(i)
          } else {
            exAreaInfo.uploadFileRecord.border = {}
          }
        })
      }

    }
    // 保存绘制的区域
    const saveDrawArea = () => {
      exAreaInfo.showExModal = true
      removeDraw()
      // 0为 删除 2为第二个图形还没开始绘制
      if (drawData.features.length = 1) {
        // console.log(drawData)
        // exAreaInfo.uploadFileRecord.drawInfo = drawData
        exAreaInfo.uploadFileRecord.border.first = new Array()
        exAreaInfo.uploadFileRecord.border.second = new Array()
        let feature = drawData.features[0]
        let geometry = feature!.geometry
        let coordinates = geometry!.coordinates
        if (coordinates.length > 0) {
          let borderAry = coordinates[0]
          // console.log(borderAry.length)
          if (borderAry.length >= 1) {
            //调取
            requestSomething(borderAry)
            // for (let i = 0; i < borderAry.length - 1; i++) {
            //   let pointAry = borderAry[i]
            //   transWGS84ToLocal(pointAry[1], pointAry[0]).then((res: any) => {
            //     if (res.data) {
            //       exAreaInfo.uploadFileRecord.border.first.push(res.data.x)
            //       exAreaInfo.uploadFileRecord.border.second.push(res.data.y)
            //     } else {
            //       exAreaInfo.uploadFileRecord.border = {}
            //     }
            //   })
            // }
          }
        }
      }
    }
    // 打开排除区域弹框
    const openExAreaModal = (cellId:number)=>{
      if(cellId<=0){
        message.info("请选择仓面后操作")
        return
      }
      removeDraw()
      axios.post("common/findCellExcludeAreaByCellId",{cellId:cellId}).then((res:any)=>{
        if(res.success){
          exAreaInfo.exAreaList = res.data
          // console.log(JSON.stringify(res.data))
          exAreaInfo.showExModal = true
        }else{
          message.info("获取排除信息失败")
        }
      })
    }
    const removeDraw = () => {
      if (draw) {
        maps.map.removeControl(draw)
        draw = null
      }
      isDrawSave.value = false;
    }
    // 排除区域坐标点转换
    let pointArr:any = {
      border: {
        first: [],
        second: []
      }
    }
    // 排除区域坐标点转换
    async function requestSomeDrop(dropAry:any) {
      for (let i = 0; i < dropAry.first.length; i++) {
        // let dropArray = dropAry[i]
        await transWGS84ToLocal1(dropAry.second[i], dropAry.first[i]).then((res: any) => {
          if (res.data) {
            pointArr.border.first.push(res.data.x)
            pointArr.border.second.push(res.data.y)
            console.log("---------")
            console.log(i)
          } else {
            pointArr.border.first = new Array()
            pointArr.border.second = new Array()
          }
        })
      }
    }
    // 打开排除区域坐标弹窗
    const openCoordinateModel = (record:any) => {
      let pointList = new Array()
      coordinateList.borderList = new Array()
      pointArr.border.first = new Array()
      pointArr.border.second = new Array()

      // for (let i = 0; i < record.border.first.length; i++) {
      //   transWGS84ToLocal(record.border.second[i], record.border.first[i]).then((res: any) => {
      //     if (res.data) {
      //       pointArr.border.first.push(res.data.x)
      //       pointArr.border.second.push(res.data.y)
      //     } else {
      //       pointArr.border.first = new Array()
      //       pointArr.border.second = new Array()
      //     }
      //   })
      // }
      requestSomeDrop(record.border)
      setTimeout(()=>{
        for (let j = 0; j < pointArr.border.first.length; j++) {
          pointList.push({
            first: pointArr.border.first[j],
            second: pointArr.border.second[j],
          })
        }
        coordinateList.borderList = pointList
        showCoordinateModal.value = true
      },2000)
    }
    // 排除区域坐标点下载
    const downloadBorderFile = () =>{
      // 封装我们需要导出的数据信息
      let dataList:any = []
      // 这里处理的是Excel的表头，必须放在数据结构的第一个位置
      dataList.push(["P坐标", "H坐标"])
      coordinateList.borderList.forEach((item:any) => {
        dataList.push([item.first, item.second]);
      })
      TableToExcel(dataList, "排除区域坐标点.xlsx")
    }
    // 获取所有排除区域坐标点&序号
    const getAllPoint = (cellId: number) =>{
      clearSerial()
      axios.post('/common/findCellExcludeAreaByCellId', { cellId: cellId }).then((res: any) => {
        if (res.success) {
          exAreaSerial.data.features = new Array()
          let exAreaPointList:any = new Array()

          let maxFirstArr:any = [], minFirstArr:any =[], maxSecondArr:any = [], minSecondArr:any = []
          let maxFirst, minFirst,maxSecond,minSecond
          let firstArr:any = [], secondArr:any = []
          // 获取排除区域最大经纬度、最小经纬度
          for (let x = 0; x < res.data.length; x++) {
            maxFirst = res.data[x].border.first[0]
            minFirst = res.data[x].border.first[0]
            maxSecond = res.data[x].border.second[0]
            minSecond = res.data[x].border.second[0]
            for (let y = 0; y < res.data[x].border.first.length; y++) {
              if (res.data[x].border.first[y] > maxFirst) {
                maxFirst = res.data[x].border.first[y]
              }
              if (res.data[x].border.first[y] < minFirst) {
                minFirst = res.data[x].border.first[y]
              }
              if (res.data[x].border.second[y] > maxSecond) {
                maxSecond = res.data[x].border.second[y]
              }
              if (res.data[x].border.second[y] < minSecond) {
                minSecond = res.data[x].border.second[y]
              }
            }
            maxFirstArr.push(maxFirst)
            minFirstArr.push(minFirst)
            maxSecondArr.push(maxSecond)
            minSecondArr.push(minSecond)
          }

          // 取中间值
          for (let i = 0; i < maxFirstArr.length; i++) {
            firstArr.push((maxFirstArr[i] + minFirstArr[i])/2)
            secondArr.push((maxSecondArr[i] + minSecondArr[i])/2)
          }

          for (let j = 0; j < res.data.length; j++) {
            exAreaPointList.push({
              first: firstArr[j],
              second: secondArr[j],
              serial: res.data[j].serial
            })
          }

          exAreaPointList.forEach((item:any) => {
            exAreaSerial.data.features.push({
              type: "Feature",
              geometry: {
                type: "Point",
                coordinates: [item.first, item.second]
              },
              properties: {
                'size': 0.1,
                'rotate': 0,
                'color': 'red',
                'serial': item.serial
              }
            })
          })
          addSerialLayer()
        } else {
          message.info('获取排除信息失败')
        }
      })
    }
    // 清除排除区域序号图层
    const clearSerial = () =>{
      if (maps.map.getLayer('pointLayer')) {
        maps.map.removeLayer('pointLayer')
      }
      if (maps.map.getLayer('testLayer')) {
        maps.map.removeLayer('testLayer')
      }
      if (maps.map.getSource('testSource')) {
        maps.map.removeSource('testSource')
      }
    }
    // 添加排除区域序号图层
    const addSerialLayer = () =>{
      clearSerial()
      maps.map.addSource('testSource', {type: 'geojson', data: exAreaSerial.data})
      maps.map.addLayer({
        id: 'pointLayer',
        type: 'circle',
        source: 'testSource',
        paint: {
          'circle-radius': 12,
          'circle-color': '#19A160 '
        }
      })
      maps.map.addLayer({
        id: 'testLayer',
        type: "symbol",
        // source: {
        //   type: 'geojson',
        //   data: exAreaSerial.data
        // },
        source: 'testSource',
        filter: ['!', ['has', 'point_count']],
        layout: {
          'icon-image': '',
          'visibility': 'visible',
          'text-field': '{serial}',//此属性为需要显示的字段
          'text-font': [ "DIN Offc Pro Medium", "Arial Unicode MS Bold"],
          'text-size': 15,
          'text-offset': [0, 0],
          'text-allow-overlap': true, // 是否允许文本重叠（可选，默认值为 false。
          'text-anchor': 'top',
        },
        paint: {
          // 绘制类属性
          // 文本类属性（需要设置 text-field）样式才生效
          'text-color': '#fff', // 文本的颜色
          'text-translate': [-1, -9], // 文本的平移（可选，通过平移 [x, y] 达到一定的偏移量。默认值为 [0, 0]
          'text-translate-anchor': 'map', // 文本的平移锚点，即相对的参考物（可选，可选值为 map、viewport，默认为 map）
        }
      })
    }
    //打开三检弹窗
    const openTpiModal = (cellId: number) => {
      if (cellId <= 0) {
        message.info('请选择仓面后操作')
        return
      }
      mapControl.pavLineInfo.type = -1
      mapControl.pavLineInfo.show = false
      tpiListInfo.value.showModal = true
      TpiModalInit.value.setCellId(cellId)
    }
    // 重新绘制边界
    const createTiledMap = (cellId:number)=>{
     if(inCellBaseInfo.value.kind == 8){
      return new Promise((resolve,reject)=>{
        axios.post("/tpMap/reCreatBorder",
            qs.stringify({
              cellID:cellId
            }),{
              headers: {'Content-Type': 'application/x-www-form-urlencoded'}
            }).then((res:any)=>{

          axios.post("/tpMap/reCreatReport",
              qs.stringify({
                cellID:cellId,
              }),{
                headers: {'Content-Type': 'application/x-www-form-urlencoded'}
              })
          axios.post("/tpMap/reCreatReport",
              qs.stringify({
                cellID:cellId,
              }),{
                headers: {'Content-Type': 'application/x-www-form-urlencoded'}
              })

          resolve(res.success)
        })

      })
     } else {
       return new Promise((resolve,reject)=>{
         axios.post("/nyMap/reCreatBorder",
             qs.stringify({
               cellID:cellId
             }),{
               headers: {'Content-Type': 'application/x-www-form-urlencoded'}
             }).then((res:any)=>{
           axios.post("/nyMap/reCreatReport",
               qs.stringify({
                 cellID:cellId,
               }),{
                 headers: {'Content-Type': 'application/x-www-form-urlencoded'}
               })
           axios.post("/nyMap/reCreatReport",
               qs.stringify({
                 cellID:cellId,
               }),{
                 headers: {'Content-Type': 'application/x-www-form-urlencoded'}
               })

           resolve(res.success)
         })
       })
     }
    }
    //绘制排除区域
    const drawTheBorder = (record: any) => {
      exAreaInfo.uploadFileRecord = record
      exAreaInfo.showExModal = false
      isDrawSave.value = true;
      initDraw()
    }
    // 增加一列新的排除区域
    const addExArea = ()=>{
      exAreaInfo.exAreaList.push({
        cellId:inCellBaseInfo.value.cellId,
        excludedId: -1,
        excludedName: null,
        reason: null,
        userName: userName.value,
        border: {first:new Array(),second:new Array()},
        gtmCreateTime: moment().format('yyyy-MM-DD HH:mm:ss')
      })
    }
    // 保存排除区域
    const saveExArea = (record:any)=>{
      if (lodash.isEmpty(record.excludedName) || lodash.trim(record.excludedName).length==0) {
        message.info("请输入排除区域名称")
        return
      }
      if (record.border.first.length==0) {
        message.info("请录入排除区域边界")
        return
      }
      axios.post("/common/saveCellExcludeAreaByCellIdAB",{
        cellId:record.cellId,
        excludedId:record.excludedId,
        reason:record.reason,
        excludedName:record.excludedName,
        border:record.border
      }).then((res:any)=>{
        if(res.success){
          record.excludedId = res.data.excludedId
          createTiledMap(record.cellId)

          message.info("保存成功")
        }else{
          message.info(res.msg)
        }
      })
    }
    // 删除排除区域
    const delExArea = (record:any,index:number)=>{
        if(record.excludedId>0){
          axios.post("/common/deleteCellExcludeAreaByCellId",{
            cellId:inCellBaseInfo.value.cellId,
            excludedId:record.excludedId
          }).then((res:any)=>{
            if(res.success){
              exAreaInfo.exAreaList.splice(index,1)
              createTiledMap(inCellBaseInfo.value.cellId)
              removeDraw()
              message.info("删除成功")
            }else{
              message.info(res.msg)
            }
          })
        }else{
          exAreaInfo.exAreaList.splice(index,1)
          createTiledMap(inCellBaseInfo.value.cellId)
          removeDraw()
          message.info("删除成功")
        }
    }
    // 打开文件选择框
    const openFileModal = (record:any)=>{
      exAreaInfo.uploadFileRecord = record
      document.getElementById("read-ex-area-input")?.click()
    }
    // 读取边界数据
    const readBorderFile = ()=>{
      let inputDOM:any = document.getElementById("read-ex-area-input")
      let files = inputDOM.files

      if (files[0]) {
        let reader = new FileReader();
        reader.readAsText(files[0], "UTF-8");
        reader.onload = (e: any)=>{
          try{
            let fileStr = e.target.result
            let fileStrArr = fileStr.split(",,")
            exAreaInfo.uploadFileRecord.border.first = new Array()
            exAreaInfo.uploadFileRecord.border.second = new Array()

            for (let i = 0; i < fileStrArr.length; i++) {
              let pointArr = fileStrArr[i].split(",")
              if (pointArr.length == 2) {
                exAreaInfo.uploadFileRecord.border.first.push(parseFloat(pointArr[0]))
                exAreaInfo.uploadFileRecord.border.second.push(parseFloat(pointArr[1]))
              }
            }
            console.log(JSON.stringify(exAreaInfo.uploadFileRecord))
          }catch (e){
            message.warn("导入格式错误"+e)
            console.log(e)
          }
        }
        inputDOM.value = "";
      }
    }

    onMounted(()=>{
      if(sections.value.length>0){
        cellQueryFormState.value.sections[0].sectionId = sections.value[0].sectionId
        getCellBaseInfoList(null)
      }
      // 加载地图
      initMap()

    })

    onBeforeUnmount(()=>{
      // 关闭mqtt
      MqttService.unsubscribe(realMapInfo.subscribeList);
      MqttService.end();
      // 移除地图
      maps.map.remove()
    })

    return{
      sections,
      setHeight,
      kindDict,
      cellStatusDict,
      handleCell,
      ...toRefs(mapControl),
      clickMapControl,
      clickMapEvent,
      workListInfo,
      deviceTypeDict,

      cellQueryFormRef,
      cellQueryFormState,
      cellBaseInfoList,
      inCellBaseInfo,
      getCellBaseInfoList,
      setCellStatus,

      ...toRefs(exAreaInfo),
      ...toRefs(coordinateList),
      showCoordinateModal,
      ...toRefs(exAreaSerial),
      openExAreaModal,
      openCoordinateModel,
      downloadBorderFile,
      addExArea,
      saveExArea,
      delExArea,
      saveDrawArea,
      openFileModal,
      readBorderFile,
      drawTheBorder,

      disabled,
      disabledTP,

      //三检
      openTpiModal,
      tpiListInfo,
      TpiModalInit,
      tpiStatue,

      isDrawSave,
      addSerialLayer,
    }
  },
  components:{EditOutlined,SaveOutlined,DeleteOutlined,CloseOutlined,CheckOutlined,BorderOuterOutlined,SModal,tpiModal}
})
</script>

<style lang="scss" scoped>
.monitor-box{
  display: flex;
  width: 100%;
  height: 100%;
  .left-box{
    display: flex;
    flex-direction: column;
    width: 495px;
    height: 100%;
    .control-box{
      display: flex;
      width: 100%;
      height: 262px;
      .search-box{
        width: 235px;
        height: 100%;
        padding: 12px 17px;
        box-sizing: border-box;
        ::v-deep label{
          color:#666666;
        }
        ::v-deep .ant-form-item{
          display: flex;
          margin-bottom: 10px;
        }
        ::v-deep .ant-form-item-control-wrapper{
          flex: 1;
        }
        ::v-deep .ant-select{
          width: 100%;
        }
      }
      .map-control{
        width: 240px;
        height: 100%;
        margin-left: 20px;
        padding: 10px 17px;
        box-sizing: border-box;
        .map-control-title{
          color: #333333;
          font-weight: bold;
        }
        .map-control-title:nth-of-type(n + 2){
          display: inline-block;
          margin-top: 16px;
        }
        ::v-deep .ant-checkbox-group{
          .ant-checkbox-wrapper{
            width: 100px;
            margin-right: 0px;
            border: 2px solid #1890FF;
            box-sizing: border-box;
            border-radius: 2px;
            color: #1890FF;
            font-size: 12px;
            margin-top: 8px;
            padding: 2px 2px;
            box-sizing: border-box;
            >span:nth-of-type(n + 1){
              padding-left: 4px;
              padding-right: 4px;
            }
          }
          .ant-checkbox-wrapper:nth-child(odd){
            margin-right: 6px;
          }
          .ant-checkbox-inner{
            border: 1px solid #1890FF;
          }
        }
      }
    }
    .cell-table-box{
      display: flex;
      flex-direction: column;
      width: 495px;
      flex: 1;
      margin-top: 20px;
      padding: 0 13px;
      .table-box-header{
        color: #333333;
        font-size: 18px;
        font-weight: bold;
        padding: 18px 0 10px 10px;
      }
      .table-box-center{
        width: 100%;
        flex: 1;
      }
      ::v-deep .table-icon-box{
        display: flex;
        justify-content: space-around;
        >div:hover{
          color: #1677FF;
        }
      }
    }
  }
  .right-box{
    display: flex;
    flex-direction: column;
    flex: 1;
    height: 100%;
    margin-left: 20px;
    .base-info-box{
      width: 100%;
      height: 82px;
      padding: 14px 0 0px;
    }
    .map-box{
      position: relative;
      flex: 1;
      width: 100%;
      height: 100%;
      margin-top: 20px;
      box-sizing: border-box;
      .point-info{
        z-index: 1;
        .point-header{
          display: flex;
          width: 100%;
          height: 34px;
          line-height: 34px;
          padding: 0 16px;
          box-sizing: border-box;
          justify-content: space-between;
          border-bottom: 1px solid #eeeeee;
          >span{
            font-weight: bold;
          }
          ::v-deep .anticon{
            line-height: 34px;
          }
        }
      }
      .point-info{
        display: flex;
        flex-direction: column;
        position: absolute;
        top: 40px;
        right: 5px;
        width: 220px;
        background: #FFFFFF;
        box-shadow: 0px 2px 16px 0px rgba(0, 0, 0, 0.08);
        border-radius: 2px;
        box-sizing: border-box;
        .point-content{
          display: flex;
          flex-direction: column;
          justify-content: center;
          align-items: center;
          padding: 0 16px;
          .info{
            width: 100%;
            ::v-deep .ant-row{
              line-height: 37px;
              .ant-col:first-child{
                color: #666666;
                font-weight: bold;
              }
              .ant-col:last-child{
                color: #666666;
                text-align: right;
              }
            }
          }
        }
      }
      .map-event-control{
        display:flex;
        position:absolute;
        top:5px;
        right:5px;
        height:30px;
        background-color: #FFFFFF;
        border-radius: 3px;
        z-index: 10;
        overflow: hidden;
        .map-control-button{
          width: 90px;
          height: 30px;
          font-size: 14px;
          line-height: 28px;
          text-align: center;
          border: 1px solid #f0f0f0;
          box-sizing: border-box;
          cursor:pointer;
        }
        .map-control-active{
          color: #1890FF;
        }
        .map-control-disable{
          color: #8d8d8d;
        }
      }
      #mapboxgl-box{
        display: flex;
        width: 100%;
        height: calc(100% - 6px);
        box-sizing: border-box;
      }
      .tamp-legend{
        position: absolute;
        display: flex;
        flex-direction: column;
        padding: 8px 2.5px;
        width: 84px;
        height: 100px;
        right: 5px;
        bottom: 12px;
        background: #FFFFFF;
        border-radius: 3px;
        box-sizing: border-box;
        z-index: 1;
        >div{
          display: flex;
          width: 100%;
          height: 28px;
          .legend{
            display: flex;
            justify-content: center;
            align-items: center;
            width: 28px;
            height: 28px;
            >div{
              width: 12px;
              height: 12px;
              border-radius: 50%;
            }
          }
          .legend-title{
            color: #666666;
            line-height: 28px;
            text-align: center;
          }
        }
      }
      .ex-area-btn{
        position: absolute;
        left: 5px;
        bottom: 12px;
        width: 32px;
        height: 32px;
        background: url("../../../assets/image/ex_area.png") center no-repeat;
        background-size: 18px;
        background-color: #E6F1FC;
        border: 1px solid #1677FF;
        box-sizing: border-box;
        z-index: 1;
      }
      .work-list-btn{
        position: absolute;
        left: 42px;
        bottom: 12px;
        width: 32px;
        height: 32px;
        background: url("../../../assets/image/work_list.png") center no-repeat;
        background-size: 18px;
        background-color: #E6F1FC;
        border: 1px solid #1677FF;
        box-sizing: border-box;
        z-index: 1;
      }
      // 三检
      .tpi-list-btn {
        position: absolute;
        left: 79px;
        bottom: 12px;
        width: 32px;
        height: 32px;
        background: url('../../../assets/image/tpi_list.png') center no-repeat;
        background-size: 18px;
        background-color: #e6f1fc;
        border: 1px solid #1677ff;
        box-sizing: border-box;
        z-index: 1;
      }
    }
  }
}
.smodal-box{
  box-sizing: border-box;
}
.smodal-to-cell{
  width: 100%;
  height: 100%;
}
.ex-area-modal{
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  .ex-table-box{
    flex: 1;
    padding-top: 10px;
  }
  .ex-area-btn-box{
    display: flex;
    justify-content: flex-end;
    width: 100%;
    height: 48px;
  }
}
.coor-table-box {
  display: flex;
  flex-direction: column;
  width: 100%;
  height: 100%;
  .down-btn-box {
    display: flex;
    justify-content: flex-end;
    width: 100%;
    height: 48px;
    margin-top: 20px;
  }
}
::v-deep .mapboxgl-control-container {
  display: block;

  .mapboxgl-ctrl-bottom-left {
    display: none;
  }
}
::v-deep .mapboxgl-ctrl {
  display: block !important;
}
.draw-save {
  position: absolute;
  top: 80px;
  left: 10px;
  text-align: center;
}
</style>

